<script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/htmlUtils.js"></script>

<script type="text/javascript">
    RED.nodes.registerType('knxUltimateGarageDoorBarrierOpener', {
        category: "KNX Ultimate",
        color: '#C7E9C0',
        defaults: {
            //buttonState: {value: true},
            server: { type: "knxUltimate-config", required: true },
            name: { value: "" },
            topic: { value: "" },
            GACommand: { value: "" },
            GAStatus: { value: "" },
            GAMoving: { value: "" },
            GAImpulse: { value: "" },
            GABlocking: { value: "" },
            GAObstructionDetected: { value: "" },
            valueStatusWhenOpen: { value: true },
            valueCommandToOpen: { value: true },
            blockingTimeout: { value: 0 },
            onCommandReceivedWhileMoving: { value: "ignore" },
            timeToFullyOpen: { value: 20, required: true, validate: RED.validators.number() },
            timeToFullyClosed: { value: 20, required: true, validate: RED.validators.number() }
        },
        inputs: 0,
        outputs: 1,
        icon: "node-knx-icon.svg",
        label: function () {
            return this.name || "Garage/Door/Barrier opener"
        },
        paletteLabel: "KNX Garage opener",
        // button: {
        //     enabled: function() {
        //         // return whether or not the button is enabled, based on the current
        //         // configuration of the node
        //         return !this.changed
        //     },
        //     visible: function() {
        //         // return whether or not the button is visible, based on the current
        //         // configuration of the node
        //         return this.hasButton
        //     },
        //     //toggle: "buttonState",
        //     onclick: function() {}
        // },
        oneditprepare: function () {
            // Go to the help panel
            try {
                RED.sidebar.show("help");
            } catch (error) { }

            var node = this;
            var oNodeServer = RED.nodes.node($("#node-input-server").val()); // Store the config-node


            function getGroupAddressSimple(_sourceWidgetAutocomplete, _additionalSearchTerm) {
                $(_sourceWidgetAutocomplete).autocomplete({
                    minLength: 0,
                    source: function (request, response) {
                        //$.getJSON("csv", request, function( data, status, xhr ) {
                        $.getJSON("knxUltimatecsv?nodeID=" + $("#node-input-server").val() + "&" + { _: new Date().getTime() }, (data) => {
                            response(
                                $.map(data, function (value, key) {
                                    var sSearch = value.ga + " (" + value.devicename + ") DPT" + value.dpt;
                                    for (let index = 0; index < _additionalSearchTerm.length; index++) {
                                        const sDPT = _additionalSearchTerm[index];
                                        if (htmlUtilsfullCSVSearch(sSearch, request.term + " " + sDPT)) {
                                            return {
                                                label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display
                                                value: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display
                                            };
                                        }
                                    };
                                })
                            );
                        });
                    },
                    select: function (event, ui) {
                        // Sets Datapoint and device name automatically
                        const sDevName = ui.item.value.trim();
                        $(_sourceWidgetAutocomplete).val(sDevName);
                    },
                }).focus(function () {
                    $(this).autocomplete('search', $(this).val() + 'exactmatch');
                });
            }



            if (oNodeServer === undefined) {
                // Hide the UI
                $("#divMain").hide();
            } else {
                $("#divMain").show();
                $("#tabs").tabs();
                getGroupAddressSimple("#node-input-GACommand", ["1."]);
                getGroupAddressSimple("#node-input-GAStatus", ["1."]);
                getGroupAddressSimple("#node-input-GAMoving", ["1."]);
                getGroupAddressSimple("#node-input-GAImpulse", ["1."]);
                getGroupAddressSimple("#node-input-GAObstructionDetected", ["1."]);
                getGroupAddressSimple("#node-input-GABlocking", ["1."]);
            }





        },
        oneditsave: function () {
            // Return to the info tab
            try {
                RED.sidebar.show("info");
            } catch (error) { }


        },
        oneditcancel: function () {
            // Return to the info tab
            try {
                RED.sidebar.show("info");
            } catch (error) { }


        }
    })

</script>

<script type="text/html" data-template-name="knxUltimateGarageDoorBarrierOpener">


<div class="form-row">
    <b>KNX Garage/Door/Barrier opener</b>
    <br />
    <br />

    <label for="node-input-server">
        <i class="fa fa-circle-o"></i> Gateway
    </label>
    <input type="text" id="node-input-server" />
</div>

<div id="divMain">
    <div class="form-row">
        <label for="node-input-name">
            <i class="fa fa-tag"></i> Name
        </label>
        <input type="text" id="node-input-name" />
    </div>
    <div class="form-row">
        <label for="node-input-topic">
            <i class="fa fa-tasks"></i> Topic
        </label>
        <input type="text" id="node-input-topic" />
    </div>

    <div id="tabs">
        <ul>
          <li><a href="#tabs-1"><i class="fa-solid fa-toggle-on"></i> Group Address Input</a></li>
          <li><a href="#tabs-2"><i class="fa-solid fa-long-arrow-right"></i> Group Address Output</a></li>          
          <li><a href="#tabs-3"><i class="fa-solid fa-code-merge"></i> Timing/Behaviours</a></li>
        </ul>
        <div id="tabs-1">
          <p>
            <div class="form-row">
                <label for="node-input-GAImpulse">
                    <i class="fa fa-question-circle"></i> Impulse
                </label>
                <input type="text" id="node-input-GAImpulse" placeholder="Type name or group address" />
            </div>
            <div class="form-row">
                <label for="node-input-GACommand">
                    <i class="fa fa-play-circle-o"></i> Command
                </label>
                <input type="text" id="node-input-GACommand" placeholder="Type name or group address" />
            </div>
            <div class="form-row" id="node-input-valueCommandToOpen">
                <label style="width:85%" for="node-input-valueCommandToOpen">
                    <i class="fa fa-sign-in"></i> Behaviour
                </label>
                <select id="node-input-valueCommandToOpen">
                    <option value=true>True = open / False = close</option> 
                    <option value=false>True = close / False = open</option>                    
                </select>

            </div>
            <div class="form-row">
                <label for="node-input-GAStatus">
                    <i class="fa fa-question-circle"></i> Status
                </label>
                <input type="text" id="node-input-GAStatus" placeholder="Type name or group address" />
            </div>
            <div class="form-row" id="node-input-valueStatusWhenOpen">
                <label style="width:85%" for="node-input-valueStatusWhenOpen">
                    <i class="fa fa-sign-in"></i> Behaviour
                </label>
                <select id="node-input-valueStatusWhenOpen">
                    <option value=true>True = open / False = closed</option> 
                    <option value=false>True = closed / False = open</option>                    
                </select>
            </div>
            <div class="form-row">
                <label for="node-input-GABlocking">
                    <i class="fa fa-play-circle-o"></i> Blocking
                </label>
                <input type="text" id="node-input-GABlocking" placeholder="Type name or group address" />
            </div>
            <div class="form-row">
                <label for="node-input-blockingTimeout">
                    <i class="fa fa-play-circle-o"></i> Blocking timeout
                </label>
                <input type="text" id="node-input-blockingTimeout" placeholder="In seconds" />
            </div>
          </p>
        </div>
        <div id="tabs-2">
            <p>
                <div class="form-row">
                    <label for="node-input-GAObstructionDetected">
                        <i class="fa fa-question-circle"></i> Obstruction
                    </label>
                    <input type="text" id="node-input-GAObstructionDetected" placeholder="Type name or group address" />
                </div>
                <div class="form-row">
                    <label for="node-input-GAMoving">
                        <i class="fa fa-question-circle"></i> Moving
                    </label>
                    <input type="text" id="node-input-GAMoving" placeholder="Type name or group address" />
                </div>
            </p>
        </div>
        <div id="tabs-3">
            <p>
                <div class="form-row">
                    <label style="width:150px;" for="node-input-onCommandReceivedWhileMoving">
                        <i class="fa-solid fa-down-left-and-up-right-to-center"></i> While moving
                    </label>
                    <select id="node-input-onCommandReceivedWhileMoving">
                        <option value="ignore">Ignore commands received</option>
                        <option value="obey">Stop moving then obey to new commad</option>
                    </select>
                </div>  
                <div class="form-row">
                    <label style="width:150px;" for="node-input-timeToFullyOpen">
                        <i class="fa-regular fa-door-open"></i> Fully open time (s)
                    </label>
                    <input type="text" id="node-input-timeToFullyOpen" placeholder="In seconds" />
                </div>
                <div class="form-row">
                    <label style="width:150px;" for="node-input-timeToFullyClosed">
                        <i class="fa-regular fa-door-closed"></i> Fully closed time (s)
                    </label>
                    <input type="text" id="node-input-timeToFullyClosed" placeholder="In seconds" />
                </div>               
            </p>
        </div>
    </div>   
    
    
   


</div>

</script>
<script type="text/markdown" data-help-name="knxUltimateGarageDoorBarrierOpener">
<p>This node lets you control a garage/door/barrier, controlled with an impulse command (for example: push to open, push the same button to close, push the same button to stop the movement). 

**General**
|Property|Description|
|--|--|
| Gateway | Select the KNX gateway to be used |
| Name | Self explaining. The node name. |
| Topic | The msg output topic. |

**Group Address Input**  
These GA are transmitted by your devices to the node.
|Property|Description|
|--|--|
| Impulse | The KNX Group Address where you connected the impulsive command (for example: push to open, push the same button to close, push the same button to stop the movement) |
| Command | The KNX Group Address to command the movement. Pass **true** to open, **false** to close the door.|
| Invert command value | Invert the command boolean values, that becomes **true** to close, **false** to open the door.|
| Status | The KNX Group Address of the door status. It's usually the magnetic sensor mounted on the door to detect open/closed position. Must be **true** if the door is open, otherwise **flase**. It's used by the node to make coherent movements. **If leaved blank**, the status is computed using full open/full closed intervals specified in the **Timing/Behaviours** page. |
| Invert status value | Invert the status boolean values, that becomes **true** if the door is closed, otherwise **flase**. |
| Blocking | The KNX Group Address for blocking the movement. Pass **true** to open the door and block it in open status, **false** to close the door and block it in closed status.|
| Blocking timeout| Timeout, in seconds, after the blocking is restored; the door will not move and will wait further commands. Set 0 to never restoring from blocked status. Default is 0.|

**Group Address Output**  
These GA are computed ad transmitted to the KNX bus by the node itself.
|Property|Description|
|--|--|
| Obstruction | The KNX Group Address of the obstruction detection. This GA is wrote by the node, whenever it detects an obstruction during movement. It's **true** if an obstruction is detected, otherwise **flase**.|
| Moving | The KNX Group Address of the moving status. This GA is wrote by the node, whenever the garage/door/barrier is moving. It's **true** while moving, otherwise **false**.|

**Timing/Behaviours**
|Property|Description|
|--|--|
| While moving | Define the behaviour while the door is moving to reach it's end position (fully open or fully closed). For example, the door can stop and reverse the direction, or you can choose to ignore sent commands until the door reaches it's end position. |
| Fully open time | The time (in seconds) of a full movement from fully closed position to fully open position. |
| Fully closed time | The time (in seconds) of a full movement from fully open position to fully closed position. |
           

<br/>

### Outputs

1. Standard output
: payload (string|number|object) : Pin 1 is the standard output of the command.

2. Errors
: error (object) : Pin 2 Contains the detailed error message. 

### Details

`msg.payload` is used as the payload of the published message, in JSON ogbect format.

```json
msg = {
    topic: the topic you selected
    payload: { 
    }
}
````

<br/><a href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/-SamplesHome" target="_blank"><i class="fa fa-code"></i> Samples</a>

[![Donate via PayPal](https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/CodiceQR.png)](https://www.paypal.com/donate/?hosted_button_id=S8SKPUBSPK758)



</script>